package com.zhiche.lisa.bms.service.quote.impl;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.zhiche.lisa.bms.dao.mapper.quote.QuoteMapper;
import com.zhiche.lisa.bms.dao.model.contract.Contract;
import com.zhiche.lisa.bms.dao.model.contract.ContractFleetDtl;
import com.zhiche.lisa.bms.dao.model.fee.FeePayable;
import com.zhiche.lisa.bms.dao.model.quote.Quote;
import com.zhiche.lisa.bms.dao.model.quote.QuoteDtl;
import com.zhiche.lisa.bms.enums.ActivitiEnum;
import com.zhiche.lisa.bms.enums.FleetAttributeEnum;
import com.zhiche.lisa.bms.pojo.dto.fleet.FleetDTO;
import com.zhiche.lisa.bms.pojo.vo.activiti.HistoryTask;
import com.zhiche.lisa.bms.pojo.vo.contract.ContractVO;
import com.zhiche.lisa.bms.pojo.vo.quote.QuoteAndContractVO;
import com.zhiche.lisa.bms.pojo.vo.quote.QuoteAndDtlVO;
import com.zhiche.lisa.bms.service.activiti.ActivitiCommonService;
import com.zhiche.lisa.bms.service.contract.ContractFinalpayService;
import com.zhiche.lisa.bms.service.contract.ContractFleetDtlService;
import com.zhiche.lisa.bms.service.contract.ContractService;
import com.zhiche.lisa.bms.service.fee.FeePayableService;
import com.zhiche.lisa.bms.service.quote.QuoteDtlService;
import com.zhiche.lisa.bms.service.quote.QuoteService;
import com.zhiche.lisa.bms.service.utils.LspUtil;
import com.zhiche.lisa.bms.service.utils.common.AccountBindUtil;
import com.zhiche.lisa.bms.service.utils.common.identityCodeUtil.CodeUtil;
import com.zhiche.lisa.bms.utils.ToolCommonUtils;
import com.zhiche.lisa.core.supports.BaseException;
import com.zhiche.lisa.core.utils.Account.AccountUtil;
import com.zhiche.lisa.core.utils.Account.JwtAccountVO;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.task.Task;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 * 报价单主表 服务实现类
 * </p>
 *
 * @author liuanshun
 * @since 2018-10-22
 */
@Service
@Slf4j
public class QuoteServiceImpl extends ServiceImpl<QuoteMapper, Quote> implements QuoteService {
    /**
     * 导入其他Service的实现
     */
    @Autowired
    private QuoteDtlService quoteDtlService;
    @Autowired
    private ContractService contractService;
    @Autowired
    private ContractFleetDtlService contractFleetDtlService;
    @Autowired
    private ContractFinalpayService contractFinalpayService;
    @Autowired
    private LspUtil lspUtil;
    @Autowired
    private CodeUtil codeUtil;
    @Autowired
    private ActivitiCommonService activitiCommonService;
    @Autowired
    private FeePayableService feePayableService;

    /**
     * 查询报价单分页信息
     *
     * @param quotePage 包含分页信息的参数
     * @return 分页数据
     */
    @Override
    public Page<Quote> selectQuotePage(Page<Quote> quotePage) {
        //根据分页中的条件获取查询操作对象
        EntityWrapper<Quote> quoteEntityWrapper = this.bindQuoteWrapper(quotePage.getCondition());
        //返回分页数据
        return selectPage(quotePage.setCondition(new HashMap<>()), quoteEntityWrapper);
    }

    /**
     * 查询待审核的数据
     *
     * @param quotePage
     * @return
     */
    @Override
    public Page<Quote> queryWaitConfirmPage(Page<Quote> quotePage) throws Exception {
        //根据分页中的条件获取查询操作对象
        Map<String, Object> condition = quotePage.getCondition();
        EntityWrapper<Quote> quoteEntityWrapper = this.bindQuoteWrapper(condition);
        // 2019-01-16不限定人员可以看
        //if (condition != null) {
        //    quoteEntityWrapper.andNew();
        //    if (condition.get(ActivitiEnum.CURRENT_USER_ID) != null) {
        //        quoteEntityWrapper.eq("confirm_user", condition.get(ActivitiEnum.CURRENT_USER_ID));
        //    }
        //    if (condition.get(ActivitiEnum.CURRENT_USER_NAME) != null) {
        //        quoteEntityWrapper.or();
        //        quoteEntityWrapper.eq("activiti_task_assignee", condition.get(ActivitiEnum.CURRENT_USER_NAME));
        //    }
        //}
        if (condition != null) {
            if ("10".equals(condition.get("confirmTask"))) {
                if (condition.get(ActivitiEnum.CURRENT_USER_ID) != null) {
                    quoteEntityWrapper.eq("confirm_user", condition.get(ActivitiEnum.CURRENT_USER_ID));
                }
            }
            if ("20".equals(condition.get("confirmTask"))) {
                if (condition.get(ActivitiEnum.CURRENT_USER_NAME) != null) {
                    quoteEntityWrapper.like("activiti_task_assignee", condition.get(ActivitiEnum.CURRENT_USER_NAME).toString());
                }
            }
        }
        quotePage.setRecords(baseMapper.selectPage(quotePage, quoteEntityWrapper));
        return quotePage;
    }

    /**
     * 审核确认
     *
     * @param id
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void computeQuoteTask(Long id) throws Exception {
        Quote quote = this.selectById(id);
        if (quote != null && org.apache.commons.lang3.StringUtils.isNotBlank(quote.getActivitiTaskId())) {
            // 校验审批权限
            JwtAccountVO account = AccountUtil.getAccountInfoFromSecurityContext();
            checkConfirmPermiss(quote, account);
            String type = null;
            String typeName = null;
            if (FleetAttributeEnum.TEMP_ATTRIBUTE.getCode().equals(quote.getSubType())) {
                // 临时
                // type = checkTempPremium(quote.getPremium());
                // 2019-07-23 默认走两个流程 - 不判断溢价率
                type = ActivitiEnum.TMEP_QUOTE_RATE_2.getCode();
                typeName = ActivitiEnum.TEMP_QUOTE_CONDITION.getCode();
            } else if (FleetAttributeEnum.OFFICIAL_ATTRIBUTE.getCode().equals(quote.getSubType())) {
                // 正式
                // type = checkPremium(quote.getPremium());
                // typeName = ActivitiEnum.COMMON_QUOTE_CONDITION.getCode();
                type = ActivitiEnum.getAccountUser(account.getUsername());
                typeName = ActivitiEnum.CON_QUOTE_CONDITION.getCode();
            }
            if (!StringUtils.isEmpty(type) && !StringUtils.isEmpty(typeName)) {
                if (FleetAttributeEnum.TEMP_ATTRIBUTE.getCode().equals(quote.getSubType())) {
                    // 临时
                    Map<String, Object> map = Maps.newHashMap();
                    map.put(typeName, type);
                    activitiCommonService.taskComplete(quote.getActivitiTaskId(), map);
                } else if (FleetAttributeEnum.OFFICIAL_ATTRIBUTE.getCode().equals(quote.getSubType())) {
                    // 正式
                    // commleteCurrentTask(typeName, type, quote);
                    // activitiCommonService.taskComplete(quote.getActivitiTaskId());

                    // 2019-07-12
                    Task contractTask = activitiCommonService.getCurrentTaskByProcessId(quote.getActivitiProcessId());
                    if (ActivitiEnum.CONTRACT_QUOTE_JIESUAN.getCode().equals(contractTask.getTaskDefinitionKey())) {
                        Map<String, Object> map = Maps.newHashMap();
                        map.put(typeName, type);
                        activitiCommonService.taskComplete(quote.getActivitiTaskId(), map);
                        Task newCurrentTask = activitiCommonService.getCurrentTaskByProcessId(quote.getActivitiProcessId());
                        if (Objects.nonNull(newCurrentTask)) {
                            activitiCommonService.taskComplete(newCurrentTask.getId(), map);
                        }
                    } else {
                        Map<String, Object> map = Maps.newHashMap();
                        map.put(typeName, type);
                        activitiCommonService.taskComplete(quote.getActivitiTaskId(), map);
                    }
                }

                Task currentTask = activitiCommonService.getCurrentTaskByProcessId(quote.getActivitiProcessId());
                // ruwenxuAndwenwenAndrenyiConfirmTask
                if (currentTask != null) {
                    quote.setActivitiTaskName(String.format(ActivitiEnum.ASSIGNEE_FORM, currentTask.getName()));
                    quote.setActivitiTaskAssignee(currentTask.getAssignee());
                    quote.setActivitiTaskId(currentTask.getId());
                } else {
                    // 流程结束
                    quote.setState(2);
                    quote.setActivitiTaskName(ActivitiEnum.FINISH_ASSIGNEE);
                    quote.setActivitiTaskAssignee(null);
                    quote.setActivitiTaskId(null);
                }
                updateAllColumnById(quote);
            }
        }
    }

    private void commleteCurrentTask(String typeName, String type, Quote quote) throws Exception {
        Task oldTask = activitiCommonService.getCurrentTaskByProcessId(quote.getActivitiProcessId());
        if (ActivitiEnum.RUWX_WENWEN_RENYI.getCode().equals(oldTask.getAssignee())) {
            // 经营会计
            Map<String, Object> map = Maps.newHashMap();
            map.put(ActivitiEnum.KUAIJI_NAME_CONDITION.getCode(), ActivitiEnum.kuaijiMap.get(AccountUtil.getAccountInfoFromSecurityContext().getUsername()));
            activitiCommonService.taskComplete(quote.getActivitiTaskId(), map);
            Task currentTask = activitiCommonService.getCurrentTaskByProcessId(quote.getActivitiProcessId());
            activitiCommonService.taskComplete(currentTask.getId());
        } else if (ActivitiEnum.SHIYH_TASK_CONFIRM.getCode().equals(oldTask.getAssignee())) {
            // 施永鸿
            Map<String, Object> map = Maps.newHashMap();
            if (!ActivitiEnum.CONDITION_TYPE_1.getCode().equals(type)) {
                map.put(typeName, ActivitiEnum.CONDITION_TYPE_2.getCode());
            } else {
                map.put(typeName, type);
            }
            activitiCommonService.taskComplete(quote.getActivitiTaskId(), map);
        } else if (ActivitiEnum.DAILIJUN_TASK_CONFIRM.getCode().equals(oldTask.getAssignee())) {
            // 戴丽君
            Map<String, Object> map = Maps.newHashMap();
            if (!ActivitiEnum.CONDITION_TYPE_1.getCode().equals(type)) {
                map.put(typeName, ActivitiEnum.FOUR_CONDITION.getCode());
            } else {
                map.put(typeName, ActivitiEnum.CONDITION_TYPE_3.getCode());
            }
            activitiCommonService.taskComplete(quote.getActivitiTaskId(), map);
        } else if (ActivitiEnum.JIANGTIANXIANG_TASK_CONFIRM.getCode().equals(oldTask.getAssignee())) {
            // 蒋天祥
            Map<String, Object> map = Maps.newHashMap();
            if (ActivitiEnum.CONDITION_TYPE_2.getCode().equals(type)) {
                map.put(typeName, ActivitiEnum.FIVE_CONDITION.getCode());
            } else if (ActivitiEnum.CONDITION_TYPE_3.getCode().equals(type)) {
                map.put(typeName, ActivitiEnum.SIX_CONDITION.getCode());
            } else {
                map.put(typeName, type);
            }
            activitiCommonService.taskComplete(quote.getActivitiTaskId(), map);
        } else {
            activitiCommonService.taskComplete(quote.getActivitiTaskId());
        }
    }

    /**
     * 判断报价单是否有审批权限
     *
     * @param quote
     */
    private void checkConfirmPermiss(Quote quote, JwtAccountVO account) {
        // 校验
        if (account == null || StringUtils.isEmpty(account.getUsername())) {
            throw new BaseException("获取不到当前登录用户, 请重新登录!");
        } else {
            if (FleetAttributeEnum.OFFICIAL_ATTRIBUTE.getCode().equals(quote.getSubType())) {
                // 正式报价单
                if (!ActivitiEnum.conQuoteConfirmList.contains(account.getUsername())) {
                    throw new BaseException("当前登录用户没有审批当前节点的权限!");
                }
            } else {
                if (ActivitiEnum.RUWX_WENWEN_RENYI.getCode().equals(quote.getActivitiTaskAssignee())) {
                    if (!quote.getActivitiTaskAssignee().contains(account.getUsername())) {
                        throw new BaseException("当前登录用户没有审批当前节点的权限!");
                    }
                } else if (!account.getUsername().equals(quote.getActivitiTaskAssignee())) {
                    throw new BaseException("当前登录用户没有审批当前节点的权限!");
                }
            }
        }
    }

    /**
     * 获取审批历史记录
     *
     * @param quoteId
     * @return
     * @throws Exception
     */
    @Override
    public List<HistoryTask> queryHistoryTaskList(Long quoteId) throws Exception {
        Quote quote = this.selectById(quoteId);
        if (quote != null && org.apache.commons.lang3.StringUtils.isNotBlank(quote.getActivitiProcessId())) {
            List<HistoryTask> historyTaskList = activitiCommonService.queryActivitiHistoryTaskList(quote.getActivitiProcessId());
            if (!CollectionUtils.isEmpty(historyTaskList)) {
                Iterator<HistoryTask> iterator = historyTaskList.iterator();
                while (iterator.hasNext()) {
                    HistoryTask next = iterator.next();
                    // 对于中间状态的判断
                    if ((ActivitiEnum.RUWX_WENWEN_RENYI_TASK_ID.getCode().equals(next.getActivityId()) && iterator.hasNext())) {
                        iterator.remove();
                    } else if (ActivitiEnum.CONTRACT_QUOTE_JIESUAN.getCode().equals(next.getActivityId()) && iterator.hasNext()) {
                        iterator.remove();
                    }
                }
            }
            return historyTaskList;
        }
        return null;
    }

    /**
     * 审核不通过
     *
     * @param quote
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void auditFailQuote(Quote quote) throws Exception {
        if (quote == null || quote.getId() == null) {
            throw new BaseException("参数不能为空!");
        }
        Quote oldQuote = this.selectById(quote.getId());
        if (oldQuote != null && org.apache.commons.lang3.StringUtils.isNotBlank(oldQuote.getActivitiProcessId())) {
            // 校验审批权限
            JwtAccountVO account = AccountUtil.getAccountInfoFromSecurityContext();
            checkConfirmPermiss(oldQuote, account);
            Task task = activitiCommonService.getTaskByTaskId(oldQuote.getActivitiTaskId());
            if (task != null) {
                oldQuote.setActivitiTaskName(String.format(ActivitiEnum.ADUST_FAIL, task.getName(), quote.getActivitiTaskName()));
            } else {
                oldQuote.setActivitiTaskName(quote.getActivitiTaskAssignee());
            }

            // 删除节点
            activitiCommonService.deleteActivitiByProcessId(oldQuote.getActivitiProcessId(), quote.getActivitiTaskName());

            oldQuote.setActivitiTaskAssignee(null);
            oldQuote.setActivitiTaskId(null);
            oldQuote.setState(3);
            updateAllColumnById(oldQuote);

        }

    }

    /**
     * 查询报价单列表信息
     *
     * @param condition sql查询的映射条件
     * @return 报价单集合
     */
    @Override
    public List<Quote> selectQuoteList(Map<String, Object> condition) {
        //根据分页中的条件获取查询操作对象
        EntityWrapper<Quote> quoteEntityWrapper = this.bindQuoteWrapper(condition);
        //返回列表数据
        return selectList(quoteEntityWrapper);
    }

    @Override
    public List<Quote> selectQuoteListNoTenant(Map<String, Object> condition) {
        EntityWrapper<Quote> contractEntityWrapper = this.bindQuoteWrapper(condition);
        return baseMapper.selectListNoTenant(contractEntityWrapper);
    }

    /**
     * 根据合同id查询报价单列表
     *
     * @param contractId 合同id号
     * @return 报价单集合
     */
    @Override
    public List<Quote> selectQuoteListByContractId(Long contractId) {
        //绑定合同id号的条件
        Map<String, Object> condition = new HashMap<>();
        condition.put("contractId", contractId);
        //返回报检单列表数据
        return this.selectQuoteList(condition);
    }

    @Override
    public List<Quote> selectQuoteListByContractIdNoTenant(Long contractId) {//绑定合同id号的条件
        Map<String, Object> condition = new HashMap<>();
        condition.put("contractId", contractId);
        return this.selectQuoteListNoTenant(condition);
    }

    /**
     * 根据id号获取报价单列表和详明信息
     *
     * @param id 报价单id
     * @return 报价单和详明信息
     */
    @Override
    public QuoteAndDtlVO selectQuoteAndDtl(Long id) {
        QuoteAndDtlVO quoteAndDtlVO = new QuoteAndDtlVO();
        //获取报价单信息并绑定
        Quote quote = selectById(id);
        if (quote != null) {
            BeanUtils.copyProperties(quote, quoteAndDtlVO);
            //根据报价单id获取详明数据
            List<QuoteDtl> quoteDtls = quoteDtlService.selectQuoteDtlsByHeaderId(id);
            quoteAndDtlVO.setQuoteDtls(quoteDtls);
        }
        return quoteAndDtlVO;
    }

    /**
     * 根据合同id号获取报价单列表和详明信息
     *
     * @param contractId 合同id
     * @return 报价单和详明信息
     */
    @Override
    public QuoteAndDtlVO selectQuoteAndDtlByContractId(Long contractId) {
        QuoteAndDtlVO quoteAndDtlVO = new QuoteAndDtlVO();
        List<Quote> quotes = this.selectQuoteListByContractId(contractId);
        if (!CollectionUtils.isEmpty(quotes)) {
            BeanUtils.copyProperties(quotes.get(0), quoteAndDtlVO);
            //寻找详明
            List<QuoteDtl> quoteDtls = quoteDtlService.selectQuoteDtlsByHeaderId(quotes.get(0).getId());
            quoteAndDtlVO.setQuoteDtls(quoteDtls);
        }
        return quoteAndDtlVO;
    }

    /**
     * 新增一个报价单
     *
     * @param quote 报价单基本信息
     * @return 修改后的报价单
     */
    @Override
    public Quote insertOneQuote(Quote quote) {
        try {
            //创建报价单号
            quote.setCode(codeUtil.getQuoteCode().getNextCode(null));
            new AccountBindUtil<Quote>().bindCreatorAndTenantId(quote, true);//绑定tenantId和create
            //默认状态为0，设置创建时间
            quote.setGmtCreate(new Date());
            quote.setState(0);
            // 2019-10-30 创建人
            JwtAccountVO account = AccountUtil.getAccountInfoFromSecurityContext();
            quote.setCreatorName(account.getUsername());
            //保存并返会被修改后的对象
            insert(quote);
            return quote;
        } catch (BaseException e) {
            log.error("QuoteServiceImpl.insertOneQuote error: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("QuoteServiceImpl.insertOneQuote error: {}", e.getMessage());
            throw new BaseException("新增报价单错误");
        }
    }

    /**
     * 新增一个报价单及详明
     *
     * @param quoteAndDtlVO 报价单和详明的封装对象
     * @return 修改后的报价单和详明数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public QuoteAndDtlVO insertQuoteAndDtl(QuoteAndDtlVO quoteAndDtlVO) {
        try {
            if (quoteAndDtlVO == null) {
                return null;
            }
            if (Objects.deepEquals(new Integer(0), quoteAndDtlVO.getSubType())) {
                HashMap<String, Object> condition = new HashMap<>();
                condition.put("subType", 0);
                condition.put("notState", 4);
                condition.put("comCode", quoteAndDtlVO.getComCode());
                List<Quote> quotes = this.selectQuoteList(condition);
                if (!CollectionUtils.isEmpty(quotes)) {
                    throw new BaseException("已存在相同指令号的有效报价单");
                }
            }
            Quote quote = new Quote();
            //获取封装对象的报价单信息
            BeanUtils.copyProperties(quoteAndDtlVO, quote);
            //新增报价单
            packageQuoteDate(quote);
            this.insertOneQuote(quote);
            //新增报价单详明
            List<QuoteDtl> quoteDtls = quoteDtlService.insertQuotesBySourceAndHeaderId(quoteAndDtlVO.getQuoteDtls(), quote.getId());
            //保存修改后的实体
            quoteAndDtlVO.setQuoteDtls(quoteDtls);
        } catch (BaseException e) {
            log.error("QuoteServiceImpl.insertQuoteAndDtl error: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("QuoteServiceImpl.insertQuoteAndDtl error: {}", e.getMessage());
            throw new BaseException("新增报价单及详明错误");
        }
        return quoteAndDtlVO;
    }


    /**
     * 时间转换
     *
     * @param quote
     */
    private void packageQuoteDate(Quote quote) {
        if (Objects.nonNull(quote.getEffectiveDate())) {
            // 获取一天最早
            quote.setEffectiveDate(ToolCommonUtils.getStartOfDate(quote.getEffectiveDate()));
        }
        if (Objects.nonNull(quote.getInvalidDate())) {
            // 加一天减去一秒
            quote.setInvalidDate(ToolCommonUtils.getEndOfDate(quote.getInvalidDate()));
        }
    }

    /**
     * 创建临时合同
     *
     * @param quoteAndContractVO 包含合同附加信息的吧报价单封装对象
     * @param token              访问其他项目的访问通行证
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void createTemporaryContract(QuoteAndContractVO quoteAndContractVO, String token) {
        try {
            //获取报价单
            Long quoteId = quoteAndContractVO.getId();
            Quote quote = this.selectById(quoteId);
            //判断类型是否是临时合同
            if (Objects.deepEquals(0, quote.getSubType())) {
                String comCode = quote.getComCode();
                if (!Strings.isNullOrEmpty(comCode)) {
                    Map<String, Object> orderCodeFeeMap = new HashMap<>();
                    orderCodeFeeMap.put("order_code", comCode);
                    List<FeePayable> feePayables = feePayableService.selectFeePayableList(orderCodeFeeMap);
                    if (!CollectionUtils.isEmpty(feePayables)) {
                        FeePayable feePayable = feePayables.get(0);
                        feePayable.setElsePrice(quoteAndContractVO.getCashDeposit());
                        feePayableService.updateById(feePayable);
                    }
                }
                /*
                 * 绑定合同数据
                 */
                Contract contract = new Contract();
                contract.setContractType(0);
                if (quote.getSubId() != null) {
                    FleetDTO fleetDTO = new FleetDTO();
                    fleetDTO.setId(quote.getSubId());
                    FleetDTO fleetOne = lspUtil.getFleetOne(fleetDTO, token);
                    if (fleetOne == null) {
                        throw new BaseException("未找到对应分供方");
                    }
                    contract.setFleetTypeName(fleetOne.getPersonal());
                    contract.setFleetIds(String.valueOf(fleetOne.getId()));
                    contract.setFleetNames(fleetOne.getFleetName());
                    contract.setFirstPartyId(fleetOne.getLspId());
                    contract.setFirstPartyName(fleetOne.getLspName());
                }
//                contract.setEffectiveDate(quote.getEffectiveDate());
//                contract.setInvalidDate(quote.getInvalidDate());
                contract.setRate(quote.getRate());
                contract.setPayWay(quote.getPayType());
                contract.setPayDays(quote.getPayDays());
                contract.setContName(contract.getFleetTypeName() + "临时合同");
                contract.setContractPro(0);
                contract.setSecondPartyType(1);
                contract.setShippingType(new Long(quote.getTransType()));
                contract.setInvalidDate(quote.getInvalidDate());
                contract.setEffectiveDate(quote.getEffectiveDate());


                contract.setOilPrepayRate(quoteAndContractVO.getOilPrepayRate());
                contract.setOilFinalpayRate(quoteAndContractVO.getOilFinalpayRate());
                contract.setCashPrepayRate(quoteAndContractVO.getCashPrepayRate());
                contract.setCashFinalpayRate(quoteAndContractVO.getCashFinalpayRate());
                contract.setCashDeposit(quoteAndContractVO.getCashDeposit());
                //已审核
                if (new Integer(2).equals(quote.getState())) {
                    contract.setContState(1L);
                }
                /*
                 * 创建合同和油卡详明
                 */
                ContractFleetDtl contractFleetDtl = new ContractFleetDtl();
                contractFleetDtl.setOilPrepayRate(quoteAndContractVO.getOilPrepayRate());
                contractFleetDtl.setOilFinalpayRate(quoteAndContractVO.getOilFinalpayRate());
                contractFleetDtl.setCashPrepayRate(quoteAndContractVO.getCashPrepayRate());
                contractFleetDtl.setCashFinalpayRate(quoteAndContractVO.getCashFinalpayRate());
                contractFleetDtl.setFleetId(Long.parseLong(contract.getFleetIds()));
                contractFleetDtl.setIsPrepay(0);
                contractFleetDtl.setFleetName(contract.getFleetNames());

                ContractVO contractVO = new ContractVO();
                contractVO.setContract(contract);
                contractVO.addContractFleetDtl(contractFleetDtl);
                contractService.insertContractAndContractAccessories(contractVO);

                contractFinalpayService.insertContractFinalpayList(quoteAndContractVO.getContractFinalpays(), contract.getId());
                /*
                 * 给报价单回写合同数据,并同步修改报检单详明相关联的应付账款数据
                 */
                Quote updateQuote = new Quote();
                updateQuote.setId(quoteId);
                updateQuote.setContractId(contract.getId());
                updateQuote.setContractCode(contract.getContCode());
                this.updateOneQuote(updateQuote);

                // quoteDtlService.updateFeePayableContactByHeaderId(contract, quoteId);
            } else {
                throw new BaseException("该报价单非临时报价单");
            }
        } catch (BaseException e) {
            log.error("QuoteServiceImpl.createTemporaryContract error: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("QuoteServiceImpl.createTemporaryContract error: {}", e.getMessage());
            throw new BaseException("创建临时合同失败");
        }
    }

    /**
     * 更新报价单信息
     *
     * @param quote 包含报价单id的修改结果
     * @return 更新后的数据
     */
    @Override
    public Quote updateOneQuote(Quote quote) {
        try {
            //设置修改时间为默认值
            quote.setGmtModify(new Date());
            quote.setConfirmDate(new Date());
            packageQuoteDate(quote);
            updateById(quote);
            return quote;
        } catch (BaseException e) {
            log.error("QuoteServiceImpl.updateOneQuote error: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("QuoteServiceImpl.updateOneQuote error: {}", e.getMessage());
            throw new BaseException("更新报价单错误");
        }
    }

    /**
     * 更新报价单信息
     *
     * @param quote 包含报价单id的修改结果
     * @return 更新后的数据
     */
    @Override
    public Quote updateAllColumnOneQuote(Quote quote) {
        try {
            //设置修改时间为默认值
            quote.setGmtModify(new Date());
            quote.setConfirmDate(new Date());
            updateAllColumnById(quote);
            return quote;
        } catch (BaseException e) {
            log.error("QuoteServiceImpl.updateAllColumnOneQuote error: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("QuoteServiceImpl.updateAllColumnOneQuote error: {}", e.getMessage());
            throw new BaseException("更新报价单错误");
        }
    }

    /**
     * 更新报价单及详明信息
     *
     * @param quoteAndDtlVO 包含报价单id和关联详明信息的封装对象
     * @return 更新后报价单和详明数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public QuoteAndDtlVO updateQuoteAndDtl(QuoteAndDtlVO quoteAndDtlVO) {
        try {
            //获取报价单信息进行修改
            Quote quote = new Quote();
            BeanUtils.copyProperties(quoteAndDtlVO, quote);
            this.updateOneQuote(quote);
            //获取详明信息进行编辑
            quoteDtlService.editQuotesBySourceAndHeaderId(quoteAndDtlVO.getQuoteDtls(), quote.getId());
        } catch (BaseException e) {
            log.error("QuoteServiceImpl.updateQuoteAndDtl error: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("QuoteServiceImpl.updateQuoteAndDtl error: {}", e.getMessage());
            throw new BaseException("更新报价单及明细错误");
        }
        return quoteAndDtlVO;
    }

    /**
     * 提交审核
     *
     * @param id 被修改审核的报价单id
     * @return 更新后的数据
     */
    @Override
    public Quote submitExamine(Long id) {
        Quote quote = new Quote();
        try {
            /*
             * 验证原数据后修改状态
             */
            Quote oldQuote = selectById(id);
            if (oldQuote.getState() == null && new Integer(0).compareTo(oldQuote.getState()) != 0) {
                throw new BaseException("只能提交新增状态的报价单");
            }

            quote.setId(id);
            quote.setState(1);

            // if (FleetAttributeEnum.OFFICIAL_ATTRIBUTE.getCode().equals(oldQuote.getSubType())) {
            //     // 正式报价单
            //     startQuoteConfirm(oldQuote.getPremium(), oldQuote.getSubType(), quote);
            // } else {
            //
            //     //溢价比（溢价率）小于等于0直接通过审核
            //     if (BigDecimal.ZERO.compareTo(oldQuote.getPremium()) >= 0) {
            //         quote.setState(2);
            //     } else {
            //         startQuoteConfirm(oldQuote.getPremium(), oldQuote.getSubType(), quote);
            //     }
            // }
            // 2019-07-23 临时报价单不判断溢价率
            startQuoteConfirm(oldQuote.getPremium(), oldQuote.getSubType(), quote);
            JwtAccountVO account = AccountUtil.getAccountInfoFromSecurityContext();
            if (account != null && !StringUtils.isEmpty(account.getAccountId())) {
                quote.setConfirmUser(account.getAccountId());
            }
            this.updateOneQuote(quote);
        } catch (BaseException e) {
            log.error("QuoteServiceImpl.submitExamine error: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("QuoteServiceImpl.submitExamine error: {}", e.getMessage());
            throw new BaseException("提交审核请求失败");
        }
        return quote;
    }

    /**
     * 启动流程
     *
     * @param premium
     * @param quote
     * @throws Exception
     */
    private void startQuoteConfirm(BigDecimal premium, Integer quoteType, Quote quote) throws Exception {
        if (premium != null) {
            String pId = null;
            // 判断报价单类型
            if (FleetAttributeEnum.TEMP_ATTRIBUTE.getCode().equals(quoteType)) {
                // 临时报价单
                //String tempTypeCode = checkTempPremium(premium);
                pId = activitiCommonService.startTempQuoteWorkFlow();
            } else if (FleetAttributeEnum.OFFICIAL_ATTRIBUTE.getCode().equals(quoteType)) {
                // 正式报价单
                // 校验
                // String typeCode = checkPremium(premium);
                // if (!StringUtils.isEmpty(typeCode)) {
                //     pId = activitiCommonService.startWorkFlow(typeCode);
                // }
                pId = activitiCommonService.startWorkFlowCommon(ActivitiEnum.ACTIVITI_NAME.getCode());
            } else {
                throw new BaseException("无报价单类型, 请维护!");
            }
            quote.setActivitiProcessId(pId);
            if (!StringUtils.isEmpty(pId)) {
                Task task = activitiCommonService.getCurrentTaskByProcessId(pId);
                if (task != null) {
                    quote.setActivitiTaskId(task.getId());
                    quote.setActivitiTaskAssignee(task.getAssignee());
                    quote.setActivitiTaskName(String.format(ActivitiEnum.ASSIGNEE_FORM, task.getName()));
                }
            }
        }
    }

    /**
     * 判断类型
     *
     * @param premium
     * @return
     */
    private String checkPremium(BigDecimal premium) {
        if (premium != null) {
            //if (premium.compareTo(ActivitiEnum.ONE_PREMINUM) > 0 && premium.compareTo(ActivitiEnum.THREE_PREMINUM) <= 0) {
            if (premium.compareTo(BigDecimal.ZERO) > 0 && premium.compareTo(ActivitiEnum.THREE_PREMINUM) <= 0) {
                // 1 -> 1&<比例L≤3%
                return ActivitiEnum.CONDITION_TYPE_1.getCode();
            } else if (premium.compareTo(ActivitiEnum.THREE_PREMINUM) > 0 && premium.compareTo(ActivitiEnum.FIVE_PREMINUM) <= 0) {
                // 2 -> 3<比例L≤5%
                return ActivitiEnum.CONDITION_TYPE_2.getCode();
            } else if (premium.compareTo(ActivitiEnum.FIVE_PREMINUM) > 0) {
                // 3 -> 比例>5%
                return ActivitiEnum.CONDITION_TYPE_3.getCode();
            }
        }
        return null;
    }

    /**
     * 判断临时报价单的溢价比
     *
     * @param premium
     * @return
     */
    private String checkTempPremium(BigDecimal premium) {
        if (premium != null) {
            if (premium.compareTo(BigDecimal.ZERO) > 0 && premium.compareTo(ActivitiEnum.TEMP_RATE_ONE) < 0) {
                // 1 -> 0<比例L≤3%
                return ActivitiEnum.TMEP_QUOTE_RATE_1.getCode();
            } else if (premium.compareTo(ActivitiEnum.TEMP_RATE_TWO) >= 0) {
                // 2 -> 比例>=5%
                return ActivitiEnum.TMEP_QUOTE_RATE_2.getCode();
            }
        }
        return null;
    }

    /**
     * 作废
     *
     * @param id 被修改弃审的报价单id
     * @return 更新后的数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Quote blankOut(Long id) {
        Quote quote = new Quote();
        try {
            /*
             * 验证原数据后修改状态
             */
            Quote oldQuote = selectById(id);
            if (oldQuote.getState() == null && new Integer(0).compareTo(oldQuote.getState()) != 0) {
                throw new BaseException("只能提交新增状态的报价单");
            }
            quote.setId(id);
            quote.setState(4);
            // 删除流程
            if (org.apache.commons.lang3.StringUtils.isNotBlank(quote.getActivitiProcessId())) {
                activitiCommonService.deleteActivitiByProcessId(quote.getActivitiProcessId(), ActivitiEnum.QUOTE_BACK_OUT);
                oldQuote.setActivitiTaskAssignee(ActivitiEnum.QUOTE_BACK_OUT);
                cleanActivitiInfo(oldQuote);
            }
            this.updateOneQuote(quote);
        } catch (BaseException e) {
            log.error("QuoteServiceImpl.blankOut error: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("QuoteServiceImpl.blankOut error: {}", e.getMessage());
            throw new BaseException("作废请求提交失败");
        }
        return quote;
    }

    /**
     * 审核
     *
     * @param id 指定审核的id
     * @return 更新后的数据
     */
    @Override
    public Quote examine(Long id) {
        Quote quote = new Quote();
        try {
            /*
             * 验证原数据后修改状态
             */
            Quote oldQuote = selectById(id);
            if (oldQuote.getState() == null && new Integer(1).compareTo(oldQuote.getState()) != 0) {
                throw new BaseException("只能确认审核中的数据");
            }
            quote.setId(id);
            quote.setState(2);
            this.updateOneQuote(quote);
        } catch (BaseException e) {
            log.error("QuoteServiceImpl.examine error: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("QuoteServiceImpl.examine error: {}", e.getMessage());
            throw new BaseException("审核请求提交失败");
        }
        return quote;
    }

    /**
     * 绑定Condition条件
     *
     * @param condition 条件映射
     * @return EntityWrapper操作对象
     */
    private EntityWrapper<Quote> bindQuoteWrapper(Map<String, Object> condition) {
        EntityWrapper<Quote> entityWrapper = new EntityWrapper<Quote>();
        if (!CollectionUtils.isEmpty(condition)) {
            /*
             * 绑定结果不为空的条件
             */
            entityWrapper.orderBy("gmt_create desc, id desc");

            if (!StringUtils.isEmpty(condition.get("state"))) {
                entityWrapper.eq("state", condition.get("state"));
            } else {
                entityWrapper.ne("state", 4);
            }
            if (!StringUtils.isEmpty(condition.get("premiumNonNull"))) {
                entityWrapper.isNotNull("premium").and().gt("premium", 0);
            }
            for (Map.Entry<String, Object> item :
                    condition.entrySet()) {
                if (!StringUtils.isEmpty(item.getValue())) {
                    if ("code".equals(item.getKey())) {
                        entityWrapper.like("code", item.getValue() == null ? "" : item.getValue().toString());
                    }
                    if ("contractId".equals(item.getKey())) {
                        entityWrapper.eq("contract_id", item.getValue());
                    }
                    if ("subType".equals(item.getKey())) {
                        entityWrapper.eq("sub_type", item.getValue());
                    }
                    if ("payDays".equals(item.getKey())) {
                        entityWrapper.eq("pay_days", item.getValue());
                    }
                    if ("subId".equals(item.getKey())) {
                        entityWrapper.eq("sub_id", item.getValue());
                    }
                    if ("effectiveDateS".equals(item.getKey())) {
                        entityWrapper.ge("effective_date", item.getValue());
                    }
                    if ("effectiveDateE".equals(item.getKey())) {
                        entityWrapper.le("effective_date", item.getValue());
                    }
                    if ("subName".equals(item.getKey())) {
                        entityWrapper.eq("sub_name", item.getValue());
                    }
                    if ("contractId".equals(item.getKey())) {
                        entityWrapper.eq("contract_id", item.getValue());
                    }
                    if ("neId".equals(item.getKey())) {
                        entityWrapper.ne("id", item.getValue());
                    }
                    if ("comCode".equals(item.getKey())) {
                        entityWrapper.eq("com_code", item.getValue());
                    }
                    if ("haveContract".equals(item.getKey())) {
                        if (Objects.deepEquals("1", item.getValue())) {
                            entityWrapper.isNotNull("contract_id");
                        } else {
                            entityWrapper.isNull("contract_id");
                        }
                    }
                    if ("stateList".equals(item.getKey())) {
                        entityWrapper.in("state", JSONArray.parseArray(JSONArray.toJSONString(item.getValue())));
                    }
                    if ("termOfValidity".equals(item.getKey())) {
                        entityWrapper.le("effective_date", item.getValue());
                        entityWrapper.ge("invalid_date", item.getValue());
                    }
                    if ("notState".equals(item.getKey())) {
                        entityWrapper.ne("state", item.getValue());
                    }
                }
            }
        }
        return entityWrapper;
    }

    /**
     * 清空流程信息
     *
     * @param quote
     */
    private void cleanActivitiInfo(Quote quote) {
        quote.setActivitiTaskName(null);
        quote.setActivitiTaskId(null);
        quote.setActivitiTaskAssignee(null);
        quote.setActivitiProcessId(null);
        updateAllColumnById(quote);
    }

}
